/**
 * File:   DHTStatistics.java
 * Author: Gvennet
 */
package dht.node;

import dht.network.Network;

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * todo write javadoc
 */
public final class DHTStatistics
{

	private final DHTDataModel data;

	private final DHTNodeModel nodes;

	private final Network network;

	private final ScheduledThreadPoolExecutor scheduledExecutor;

	private final List<DHTStatisticsEventListener> listeners;

	private LinkedList<int[]> history = new LinkedList<int[]>();

	private long statisticsPeriod;

	public DHTStatistics(DHTDataModel data, DHTNodeModel nodes, Network network, ScheduledThreadPoolExecutor scheduledExecutor, long statisticsPeriod)
	{
		listeners = new LinkedList<DHTStatisticsEventListener>();
		this.data = data;
		this.nodes = nodes;
		this.network = network;
		this.scheduledExecutor = scheduledExecutor;
		this.statisticsPeriod = statisticsPeriod;
	}

	public LinkedList<int[]> getStatistics()
	{
		return history;
	}

	public void startStatisticGathering()
	{
		scheduledExecutor.execute(new StatisticsGathering());
	}

	public void addNetworkListener(DHTStatisticsEventListener listener)
	{
		listeners.add(listener);
	}

	public void removeNetworkListener(DHTStatisticsEventListener listener)
	{
		listeners.remove(listener);
	}

	private void fireUpdate(int[] actualStatisticsData)
	{
		for (DHTStatisticsEventListener listener : listeners)
		{
			listener.statisticsUpdate(actualStatisticsData);
		}
	}

	private final class StatisticsGathering implements Runnable
	{

		//@Override

		public void run()
		{
			int[] actualStatisticsData = Arrays.copyOf(network.getStatistics().getLast(), 24);

			int messages = 0;
			int size = network.getFindValueStatistics().size();
			if (size != 0)
			{
				Collection<Integer> tempCollection = network.getFindValueStatistics().values();

				for (Integer i : tempCollection)
				{
					messages = messages + i;
				}

			}

			actualStatisticsData[20] = messages;						//количество сообщений, переданных для поиска значений
			actualStatisticsData[21] = data.getStatistics();				 //количество хранимых локально данных
			actualStatisticsData[22] = nodes.getStatistics();				//количество узлов в таблице маршрутизации
			actualStatisticsData[23] = size;							//количество искомых значений

			history.add(actualStatisticsData);

			fireUpdate(actualStatisticsData);

			scheduledExecutor.schedule(new StatisticsGathering(), statisticsPeriod, TimeUnit.SECONDS);
		}

	}
}
